/**
 *  Copyright 2011 Pavlov Dm.
 *  Licensed under the MIT License
 */
 
package org.motiv.tests.core;

import org.motiv.tests.policy.ElementFactory;
import org.motiv.tests.objects.TestObject;
import org.motiv.core.Element;

import org.junit.Test;
import static org.junit.Assert.*;


/**
 * A element class tests.
 * @author Pavlov Dm
 */

 public class ElementTest{
	@Test
	public void check_getObjectKey_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		assertEquals("Check getObjectKey method",EXPECTED_KEY,element.getObjectKey());
	}
	@Test
	public void check_getKey_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		assertEquals("Check getKey method",EXPECTED_KEY,element.getKey());
	}
	@Test
	public void check_getValue_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		TestObject obj = (TestObject) element.getValue();
		assertEquals("Check getValue method for id",EXPECTED_KEY,obj.getId());
		assertEquals("Check getValue method for name",EXPECTED_NAME,obj.getName());
	}
	@Test
	public void check_getObjectValue_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		TestObject obj = (TestObject) element.getObjectValue();
		assertEquals("Check getValue method for id",EXPECTED_KEY,obj.getId());
		assertEquals("Check getValue method for name",EXPECTED_NAME,obj.getName());
	}
	@Test
	public void check_setTimeToLive_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final int EXPECTED_TIME_TO_LIVE = 10;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setTimeToLive(EXPECTED_TIME_TO_LIVE);
		assertEquals("Check setTimeToLive method",EXPECTED_TIME_TO_LIVE,element.getTimeToLive());
	}
	@Test(expected=IllegalArgumentException.class)
    public void check_setTimeToLive_method_with_exception() {
       final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final int EXPECTED_TIME_TO_LIVE = -10;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setTimeToLive(EXPECTED_TIME_TO_LIVE);
    }
	@Test
	public void check_setTimeToIdle_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final int EXPECTED_TIME_TO_IDLE = 10;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setTimeToIdle(EXPECTED_TIME_TO_IDLE);
		assertEquals("Check setTimeToIdle method",EXPECTED_TIME_TO_IDLE,element.getTimeToIdle());
	}
	@Test(expected=IllegalArgumentException.class)
    public void check_setTimeToIdle_method_with_exception() {
       final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final int EXPECTED_TIME_TO_IDLE = -10;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setTimeToIdle(EXPECTED_TIME_TO_IDLE);
    }
	@Test
	public void check_setVersion_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_VERSION = 10L;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setVersion(EXPECTED_VERSION);
		assertEquals("Check setVersion method",EXPECTED_VERSION,element.getVersion());
	}
	@Test
	public void check_getHitCount_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_HITS = 0L;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		assertEquals("Check getHitCount method",EXPECTED_HITS,element.getHitCount());
	}
	@Test
	public void check_updateAccessStatistics_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_HITS = 1L;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.updateAccessStatistics();
		assertEquals("Check updateAccessStatistics method",EXPECTED_HITS,element.getHitCount());
	}
	@Test
	public void check_resetAccessStatistics_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_HITS_BEFORE = 1L;
		final long EXPECTED_HITS_AFTER = 0L;
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.updateAccessStatistics();
		assertEquals("Check resetAccessStatistics method",EXPECTED_HITS_BEFORE,element.getHitCount());
		element.resetAccessStatistics();
		assertEquals("Check resetAccessStatistics method",EXPECTED_HITS_AFTER,element.getHitCount());
	}
	@Test
	public void check_updateUpdateStatistics_method() throws InterruptedException {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_UPDATE_TIME_BEFORE = System.currentTimeMillis();
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		assertEquals("Check updateAccessStatistics method",EXPECTED_UPDATE_TIME_BEFORE,element.getLatestOfCreationAndUpdateTime());
		Thread.sleep(50);
		final long EXPECTED_UPDATE_TIME_AFTER = System.currentTimeMillis();
		element.updateUpdateStatistics();
		assertEquals("Check updateAccessStatistics method",EXPECTED_UPDATE_TIME_AFTER,element.getLatestOfCreationAndUpdateTime());
	}
	@Test
	public void check_setCreationTime_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_CREATE_TIME = System.currentTimeMillis();
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setCreationTime(EXPECTED_CREATE_TIME);
		assertEquals("Check setCreationTime method",EXPECTED_CREATE_TIME,element.getCreationTime());
	}
	@Test
	public void check_updateLastAccessTime_method() throws InterruptedException {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_UPDATE_TIME_BEFORE = System.currentTimeMillis();
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.updateLastAccessTime(EXPECTED_UPDATE_TIME_BEFORE);
		assertEquals("Check updateLastAccessTime method",EXPECTED_UPDATE_TIME_BEFORE,element.getLastAccessTime());
		Thread.sleep(50);
		final long EXPECTED_UPDATE_TIME_AFTER = System.currentTimeMillis();
		element.resetLastAccessTime();
		assertEquals("Check updateLastAccessTime method",EXPECTED_UPDATE_TIME_AFTER,element.getLastAccessTime());
	}
	@Test
	public void check_isEternal_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setTimeToIdle(0);
		element.setTimeToLive(0);
		assertTrue("Check isEternal method",element.isEternal());
	}
	@Test
	public void check_isLifespanSet_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		assertTrue("Check isLifespanSet method",!element.isLifespanSet());
		element.setTimeToIdle(1);
		assertTrue("Check isLifespanSet method",element.isLifespanSet());
	}
	@Test
	public void check_getExpirationTime_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final int TIME_TO_LIVE = 10;
		final long CREATED_TIME = System.currentTimeMillis();
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		element.setTimeToLive(TIME_TO_LIVE);
		final long EXPECTED_EXPIRATION_TIME = CREATED_TIME+element.toMillis(TIME_TO_LIVE);
		assertEquals("Check getExpirationTime method",EXPECTED_EXPIRATION_TIME,element.getExpirationTime());
	}
	@Test
	public void check_toMillis_method() {
		final long EXPECTED_KEY = 1L;
		final String EXPECTED_NAME = "test";
		final long EXPECTED_MILLIS = 10000L; // 10 x 1000
		Element element = ElementFactory.create(EXPECTED_KEY,EXPECTED_NAME);
		assertEquals("Check toMillis method",EXPECTED_MILLIS,element.toMillis(10));
	}
}
